// rust
// `Work/basic/src/stdx/f32x/f32x.rs`
// f32 常见方法示例：sqrt, powf, powi, to_bits, from_bits, 分类方法，取整/舍入等。
// 所有示例带中文注释，便于学习与测试。

use std::f32::consts::PI;

#[allow(dead_code)]
#[test]
pub fn stdx_examples_f32x() {
    // 简短演示：开方、幂、取位表示
    let x: f32 = 4.0;
    let y = x.sqrt(); // 平方根
    let p = x.powf(3.0); // 浮点幂
    let q = x.powi(3); // 整数幂
    let recip = x.recip(); // 倒数（1/x）
    let bits = x.to_bits(); // IEEE-754 位表示（u32）
    let back = f32::from_bits(bits); // 由位表示还原
    let _ = (y, p, q, recip, bits, back);

    println!("recip： {}", recip,);
    println!("bits ： {}", bits,);
    println!("back ： {}", back);
}

/// 基本算术与特殊值
#[test]
fn basic_arithmetic_and_constants() {
    // 常量示例
    assert_eq!(f32::INFINITY.is_infinite(), true);
    assert_eq!(f32::NEG_INFINITY.is_infinite(), true);
    assert!(f32::NAN.is_nan());
    // 最大/最小/最小正数
    println!(
        "MAX={} MIN={} MIN_POSITIVE={}",
        f32::MAX,
        f32::MIN,
        f32::MIN_POSITIVE
    );

    // 简单运算：三角与常数
    let angle = PI / 4.0f32;
    let s = angle.sin();
    let c = angle.cos();
    // sin^2 + cos^2 应接近 1
    assert!((s * s + c * c - 1.0).abs() < 1e-6);
}

/// 幂与根、mul_add 演示
#[test]
fn pow_and_mul_add_examples() {
    let a: f32 = 4.0;
    assert_eq!(a.sqrt(), 2.0);
    assert_eq!(a.powf(0.5), 2.0);
    assert_eq!(2.0f32.powi(3), 8.0);

    // 精确的 fused multiply-add（当硬件支持时）
    let m = 1.5f32;
    let n = 2.0f32;
    let t = 3.0f32;
    let mad = m.mul_add(n, t); // m * n + t, 可能是 fused
    assert!((mad - (m * n + t)).abs() < 1e-7);
}

/// 取整、截断与小数部分
#[test]
fn rounding_and_truncation() {
    let v = 3.7f32;
    assert_eq!(v.floor(), 3.0);
    assert_eq!(v.ceil(), 4.0);
    assert_eq!(v.trunc(), 3.0);
    assert_eq!(v.fract(), 0.7);

    let neg = -2.3f32;
    assert_eq!(neg.round(), -2.0); // round 向最接近的整数，.5 向偶数（bankers rounding）
}

/// 浮点数分类：is_nan, is_infinite, is_finite, is_normal
#[test]
fn classification_examples() {
    let nan = f32::NAN;
    let inf = f32::INFINITY;
    let neg_inf = f32::NEG_INFINITY;
    let normal = 1.23f32;
    let subnormal = f32::MIN_POSITIVE / 2.0; // 次正规数（可能为 0 取决于实现）

    assert!(nan.is_nan());
    assert!(inf.is_infinite());
    assert!(neg_inf.is_infinite());
    assert!(normal.is_finite() && normal.is_normal());
    // 次正规数可能不是 normal
    println!(
        "subnormal: {}, is_normal: {}",
        subnormal,
        subnormal.is_normal()
    );
}

/// 位级操作：to_bits / from_bits 与构造 NaN
#[test]
fn bits_examples() {
    let x = 2.5f32;
    let bits = x.to_bits();
    let y = f32::from_bits(bits);
    assert_eq!(x, y);

    // 构造一个安静 NaN (quiet NaN)，参考 IEEE-754 编码 (示例位模式)
    let qnan_bits: u32 = 0x7FC0_0001;
    let qnan = f32::from_bits(qnan_bits);
    assert!(qnan.is_nan());

    // 注意：不同的 NaN 比较总是 false
    let nan1 = f32::NAN;
    assert!(!(nan1 == nan1));
}

/// 与 NaN 比较与排序注意事项
#[test]
fn nan_and_comparison_behavior() {
    let a = 1.0f32;
    let nan = f32::NAN;
    // 与 NaN 的任何比较（==, <, >）都是 false（except is_nan）
    assert!(!(a < nan));
    assert!(!(a > nan));
    assert!(!(a == nan));
    assert!(nan.is_nan());
}

/// 示例：使用位操作检测符号与无穷
#[test]
fn sign_and_infinite_check() {
    let neg = -3.5f32;
    // 符号检测（符号位）
    let sign_bit = neg.to_bits() >> 31;
    assert_eq!(sign_bit, 1);

    // 检查是否为无穷
    assert!(f32::INFINITY.is_infinite());
    assert!(f32::NEG_INFINITY.is_infinite());
}
